package com.live.video.server;

import com.live.video.enums.MsgTypeEnum;
import com.live.video.enums.ResultEnum;
import com.live.video.mapper.RedPacketMapper;
import com.live.video.model.MsgEntity;
import com.live.video.model.RedPacket;
import com.live.video.model.RedPacketRecord;
import com.live.video.model.User;
import com.live.video.util.MySSDBPool;
import lombok.extern.slf4j.Slf4j;
import org.nutz.ssdb4j.spi.SSDB;
import org.nutz.ssdb4j.spi.SSDBException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.List;

/**
 * Description:
 * User: godd
 * Date: 2017-11-14
 * Time: 21:26
 */
@Slf4j
@Service
public class RedPacketServer implements BaseServer<RedPacket> {

    @Autowired
    private RedPacketMapper mapper;

    @Autowired
    @Lazy
    private RedPacketRecordServer recordServer;

    @Autowired
    @Lazy
    private MySSDBPool ssdbPool;

    @Autowired
    @Lazy
    private SimpMessagingTemplate simpMessagingTemplate;

    public final static String RED_MONEY = "REDPACKET:MONEY:";// 当前组的红包金额

    public final static String RED_INCR = "REDPACKET:INCR:";// 红包限制的key
    public final static String RED_INFO = "REDPACKET:INFO:";// 红包的详细信息
    public final static String RED_LIST = "REDPACKET:LIST:";// 预先生成的红包list
    public final static String RED_RECORD = "REDPACKET:RECORD:";// 预先生成的红包详细信息
    public final static String GRAB_LIST = "GRAB:LIST:";// 抢到的用户列表
    public final static String GRAB_RECORD = "GRAB:RECORD:";// 抢到的用户信息


    /**
     * 生成红包记录,并且预先拆分好子包
     *
     * @author 戴长春    dcc@vtc365.com
     * @date 2017/12/27 22:23
     */
    @Override
    public void save(RedPacket redPacket) {
//        if (redPacket.getId() != null) {
//            mapper.updateByPrimaryKeySelective(redPacket);
//        } else {
        //存储红包信息
        redPacket.setStatus(1);
        mapper.insert(redPacket);
        //生成每条红包记录
        if (redPacket.getId() != null) {
            this.createRedPacketRecord(redPacket);
        }
//        }
    }

    @Override
    public RedPacket queryOne(RedPacket redPacket) {
        return mapper.selectOne(redPacket);
    }

    public List queryAll() {
        return null;
    }

    @Override
    public int remove(RedPacket redPacket) {
        return 0;
    }

    /**
     * 推送红包信息到直播间
     *
     * @author 戴长春    dcc@vtc365.com
     * @date 2017/11/14 21:46
     */
    public void pushMsgToRoom(RedPacket packet) {

        createRedPacketRecord(packet);
        MsgEntity msg = new MsgEntity();
        msg.setName("系统消息")
                .setType(MsgTypeEnum.RED_PACKET)
                .setContent(packet);

        simpMessagingTemplate.convertAndSend("/topic/getResponse", msg);
    }


    public void queryPacketStatus() {
//        SSDB ssdb = vsp.borrowSSDB();
//        String incrKey = RED_INCR + redPacketId;
//        String infoKey = RED_INFO + redPacketId;
//        //1.先判断用户是否抢过这个红包
//        String grabRecordKey = GRAB_RECORD + redPacketId + ":" + wxOpenId;
//
//        Map<String, Vector<Map<String, String>>> returnInfo = new HashMap<String, Vector<Map<String, String>>>();
//
//        if (ssdb.hget(grabRecordKey, "allAmount").ok()) {
//            Log.d(TAG, "queryPacketStatus : " + ResultEnum.REDPACKET_IS_GETTED.getMsg());
//
//            Vector<Map<String, String>> myGrabInfo = new Vector<Map<String, String>>();
//            myGrabInfo.add(ssdb.hgetall(grabRecordKey).mapString());
//            returnInfo.put("myGrabInfo", myGrabInfo);
//            getGrabedListFromSSDB(returnInfo);
//            return error(ResultEnum.REDPACKET_IS_GETTED, returnInfo);
//        }
//
//        //2.判断红包还有没有 返回红包信息
//        int count = 0;
//        try {
//            count = ssdb.get(incrKey).check().asInt();
//        } catch (Exception e) {
//            Log.d(TAG, "queryPacketStatus : incrKey=" + incrKey + " count not_found");
//        }
//
//        int maxCount = 0;// 红包最大数量
//        try {
//            maxCount = ssdb.hget(infoKey, "count").check().asInt();
//        } catch (Exception e) {
//            Log.d(TAG, "queryPacketStatus : infoKey=" + infoKey + " maxCount not_found");
//        }
//
//        Vector<Map<String, String>> redPacketInfo = new Vector<Map<String, String>>();
//        redPacketInfo.add(ssdb.hgetall(infoKey).mapString());
//        returnInfo.put("redPacketInfo", redPacketInfo);
//
//        if (count >= maxCount) {
//            Log.d(TAG, "queryPacketStatus : " + ResultEnum.REDPACKET_IS_OVER.getMsg());
//            return error(ResultEnum.REDPACKET_IS_OVER, returnInfo);
//        }
    }

    public void grapRedPacket(Integer redPacketId, User user) {
        SSDB ssdb = ssdbPool.borrowSSDB();
        String incrKey = RED_INCR + redPacketId;
        String listKey = RED_LIST + redPacketId;
        String infoKey = RED_INFO + redPacketId;

        // 抢红包的人数加一
        int count = ssdb.incr(incrKey, 1).asInt();
        log.info("grabRedPacket : incrKey = {}", count);

        // 红包最大数量
        int maxCount = 0;
        try {
            maxCount = ssdb.hget(infoKey, "count").check().asInt();
        } catch (Exception e) {
            log.error("grabRedPacket : infoKey= {} maxCount not_found", infoKey);
        }

        if (count > maxCount) {
            ssdb.incr(incrKey, -1);
            log.info("grabRedPacket : {}", ResultEnum.REDPACKET_IS_OVER.getMsg());
        } else {
            /**
             * 根据红包id及用户openid判断该用户是否已经抢过该红包
             */
            String grabListKey = GRAB_LIST + redPacketId;
            String grabRecordKey = GRAB_RECORD + redPacketId + ":" + user.getId();

            if (ssdb.hget(grabRecordKey, "allAmount").ok()) {
                ssdb.incr(incrKey, -1);
                log.info("grabRedPacket : {}", ResultEnum.REDPACKET_IS_OVER.getMsg());
            }

            Long time = System.currentTimeMillis();
            // 弹出一条红包记录
            int redTid = 0;
            try {
                redTid = ssdb.qpop_front(listKey).check().asInt();
                log.info("grabRedPacket : redTid = {}", redTid);
            } catch (SSDBException e) {
                log.error(e.getMessage());
            }

            String redPacketKey = RED_RECORD + redTid;

            //获取红包信息存储到信息list中
            String amount = "";
            String isBest = "";

            try {
                amount = ssdb.hget(redPacketKey, "amount").check().asString();
                isBest = ssdb.hget(redPacketKey, "isBest").check().asString();
            } catch (SSDBException e) {
                log.error(e.getMessage());
            }

            log.info("grabRedPacket : grabListKey = {}", grabListKey);
            log.info("grabRedPacket : grabRecordKey = {}", grabRecordKey);

            //存储用户信息到抢到红包的列表中
            ssdb.qpush_back(grabListKey, grabRecordKey);
            // 存微信用户的基本信息
            ssdb.hset(grabRecordKey, "userId", user.getId());
            ssdb.hset(grabRecordKey, "userName", user.getName());
            ssdb.hset(grabRecordKey, "userHeadImg", user.getHeadImg());
            ssdb.hset(grabRecordKey, "amount", amount);
            ssdb.hset(grabRecordKey, "isBest", isBest);
            ssdb.hset(grabRecordKey, "time", time);
            ssdb.hset(grabRecordKey, "allAmount", ssdb.hget(infoKey, "amount").asString());

            String topic = ssdb.hget(infoKey, "topic").asString();
            ssdb.hset(grabRecordKey, "topic", topic);

            if (count == maxCount) {
                String createTime = ssdb.hget(infoKey, "createTime").asString();
                Long drawTime = 0L;
                try {
                    Timestamp timestamp = Timestamp.valueOf(createTime);
                    long ct = timestamp.getTime();
                    drawTime = time - ct;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //存数据库
                ssdb.hset(infoKey, "drawTime", drawTime);
            }

            // 拿到红包的相关信息-钱数
            log.info("grabRedPacket : success! amount = {} ", amount);
        }
    }

    /**
     * 生成红包记录
     *
     * @author 戴长春    dcc@vtc365.com
     * @date 2017/11/14 22:17
     */
    private void createRedPacketRecord(RedPacket packet) {
        //红包总金额
        int amount = packet.getAmount();
        //红包总数
        int count = packet.getCount();
        int redPacketId = packet.getId();

        int remainSize = count;
        int remainMoney = amount;

        SSDB ssdb = ssdbPool.borrowSSDB();
        for (int i = 0; i < count; i++) {
            Integer recordAmount = getRandomMoney(remainSize, remainMoney);
            remainMoney = remainMoney - recordAmount;
            remainSize--;
            // 往数据库插入红包记录
            RedPacketRecord record = new RedPacketRecord();
            record.setAmount(recordAmount);
            record.setRedPacketId(packet.getId());
            recordServer.save(record);

            String key = RED_RECORD + packet.getId();
            ssdb.hset(key, "amount", recordAmount);
            ssdb.hset(key, "isBest", "0");
            String key4Red = RED_LIST + packet.getId();
            log.info(" rpush key= {} ,value={}", key4Red, record.getId().toString());
            ssdb.qpush_back(key4Red, record.getId());
        }

        // 获取手气最佳的并更新
        recordServer.updateBest(redPacketId);
    }

    /**
     * @param remainSize  剩余的红包数量
     * @param remainMoney 剩余的钱
     * @return money
     * @description 随机分配钱数
     */
    public int getRandomMoney(int remainSize, int remainMoney) {
        if (remainSize == 1 || remainMoney == 0) {
            return remainMoney;
        }
        int min = 1;
        int max = remainMoney / remainSize * 2;
        double money = Math.random() * max;
        money = money <= min ? 1 : money;
        return (int) money;
    }
}
